[DefaultProperty("DataSourceID"), Designer("System.Web.UI.Design.WebControls.BaseDataBoundControlDesigner, System.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
public abstract class BaseDataBoundControl : WebControl
{
    // Fields
    private object _dataSource;
    private bool _inited;
    private bool _preRendered;
    private bool _requiresBindToNull;
    private bool _requiresDataBinding;
    private bool _throwOnDataPropertyChange;
    private static readonly object EventDataBound = new object();

    // Events
    [WebCategory("Data"), WebSysDescription("BaseDataBoundControl_OnDataBound")]
    public event EventHandler DataBound
    {
        add
        {
            base.Events.AddHandler(EventDataBound, value);
        }
        remove
        {
            base.Events.RemoveHandler(EventDataBound, value);
        }
    }

    // Methods
    [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
    protected BaseDataBoundControl()
    {
    }

    protected void ConfirmInitState()
    {
        this._inited = true;
    }

    public override void DataBind()
    {
        if (base.DesignMode)
        {
            IDictionary designModeState = this.GetDesignModeState();
            if (((designModeState == null) || (designModeState["EnableDesignTimeDataBinding"] == null)) && (base.Site == null))
            {
                return;
            }
        }
        this.PerformSelect();
    }

    protected virtual void EnsureDataBound()
    {
        try
        {
            this._throwOnDataPropertyChange = true;
            if (this.RequiresDataBinding && (this.IsDataBindingAutomatic || this._requiresBindToNull))
            {
                this.DataBind();
                this._requiresBindToNull = false;
            }
        }
        finally
        {
            this._throwOnDataPropertyChange = false;
        }
    }

    protected virtual void OnDataBound(EventArgs e)
    {
        EventHandler handler = base.Events[EventDataBound] as EventHandler;
        if (handler != null)
        {
            handler(this, e);
        }
    }

    protected virtual void OnDataPropertyChanged()
    {
        if (this._throwOnDataPropertyChange)
        {
            throw new HttpException(SR.GetString("DataBoundControl_InvalidDataPropertyChange", new object[] { this.ID }));
        }
        if (this._inited)
        {
            this.RequiresDataBinding = true;
        }
    }

    protected internal override void OnInit(EventArgs e)
    {
        base.OnInit(e);
        if (this.Page != null)
        {
            this.Page.PreLoad += new EventHandler(this.OnPagePreLoad);
            if (!base.IsViewStateEnabled && this.Page.IsPostBack)
            {
                this.RequiresDataBinding = true;
            }
        }
    }

    protected virtual void OnPagePreLoad(object sender, EventArgs e)
    {
        this._inited = true;
        if (this.Page != null)
        {
            this.Page.PreLoad -= new EventHandler(this.OnPagePreLoad);
        }
    }

    protected internal override void OnPreRender(EventArgs e)
    {
        this._preRendered = true;
        this.EnsureDataBound();
        base.OnPreRender(e);
    }

    protected abstract void PerformSelect();
    protected abstract void ValidateDataSource(object dataSource);

    // Properties
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Bindable(true), WebCategory("Data"), DefaultValue((string) null), Themeable(false), WebSysDescription("BaseDataBoundControl_DataSource")]
    public virtual object DataSource
    {
        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        get
        {
            return this._dataSource;
        }
        set
        {
            if (value != null)
            {
                this.ValidateDataSource(value);
            }
            this._dataSource = value;
            this.OnDataPropertyChanged();
        }
    }

    [WebSysDescription("BaseDataBoundControl_DataSourceID"), DefaultValue(""), Themeable(false), WebCategory("Data")]
    public virtual string DataSourceID
    {
        get
        {
            object obj2 = this.ViewState["DataSourceID"];
            if (obj2 != null)
            {
                return (string) obj2;
            }
            return string.Empty;
        }
        set
        {
            if (string.IsNullOrEmpty(value) && !string.IsNullOrEmpty(this.DataSourceID))
            {
                this._requiresBindToNull = true;
            }
            this.ViewState["DataSourceID"] = value;
            this.OnDataPropertyChanged();
        }
    }

    protected bool Initialized
    {
        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        get
        {
            return this._inited;
        }
    }

    protected bool IsBoundUsingDataSourceID
    {
        get
        {
            return (this.DataSourceID.Length > 0);
        }
    }

    protected internal bool IsDataBindingAutomatic
    {
        get
        {
            if (!this.IsBoundUsingDataSourceID)
            {
                return this.IsUsingModelBinders;
            }
            return true;
        }
    }

    protected virtual bool IsUsingModelBinders
    {
        get
        {
            return false;
        }
    }

    protected bool RequiresDataBinding
    {
        [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
        get
        {
            return this._requiresDataBinding;
        }
        set
        {
            if (((value && this._preRendered) && (this.IsDataBindingAutomatic && (this.Page != null))) && !this.Page.IsCallback)
            {
                this._requiresDataBinding = true;
                this.EnsureDataBound();
            }
            else
            {
                this._requiresDataBinding = value;
            }
        }
    }

    public override bool SupportsDisabledAttribute
    {
        get
        {
            return (this.RenderingCompatibility < VersionUtil.Framework40);
        }
    }
}